package client;

import common.*;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;


import javax.swing.JComponent;

public class Canvas extends JComponent {

	public static final int FIELDSIZE = 40;
	public static final int OFFSET = 20;
	public final int WALLTHICKNESS = 4;
	
	private final int DEFAULT_FIELD_WIDTH = 10;
	private final int DEFAULT_FIELD_HEIGHT = 10;

	final int COINRADIUS = 6;
	final int COINFIELDOFFSET = FIELDSIZE/2 - COINRADIUS;
	final int PLAYERRADIUS = 15;
	final int PLAYERFIELDOFFSET = FIELDSIZE/2 - PLAYERRADIUS;
	
	private static final long serialVersionUID = 1L;
	
	private Image mImage; // used for double buffering
	private Level level;
	private Player[] player;
	private Boolean coin[][];
	private int playfieldWidth;
	private int playfieldHeight;
	
	public Canvas() {
		playfieldWidth = FIELDSIZE * DEFAULT_FIELD_WIDTH;
		playfieldHeight = FIELDSIZE * DEFAULT_FIELD_HEIGHT;
	}

	/*
	 * zeichnet spielfeld, spieler und punkte
	 */
	private void draw( Graphics g ){
		
  		// draw Background and border
		g.setColor( Color.WHITE );
	  	g.fillRect( OFFSET, OFFSET, playfieldWidth, playfieldHeight);
	  	g.setColor( Color.BLACK );
	  	g.drawRect( OFFSET, OFFSET, playfieldWidth, playfieldHeight);
	  	g.drawRect( OFFSET-2, OFFSET-2, playfieldWidth+4, playfieldHeight+4);

	  	
	  	
	  	if (level != null)
	  		drawLevel(g);
		
	  	if (player != null)
			for( Player p : player ) {
				if (p != null){
					drawPlayer(g, p);
				}
			}
	}

  
  	private void drawLevel( Graphics g ){
  		
	  	//grid
  		g.setColor( Color.LIGHT_GRAY );
	  	for( int i = 1; i < level.getColumnAmount(); i++){
	  		g.drawLine( OFFSET+i*FIELDSIZE, OFFSET, OFFSET+i*FIELDSIZE, OFFSET+playfieldHeight);
	  	}
	  	for( int i = 1; i < level.getRowAmount(); i++){
	  		g.drawLine( OFFSET, OFFSET+i*FIELDSIZE, OFFSET+playfieldWidth, OFFSET+i*FIELDSIZE);
	  	}
	  	
	  	//walls and coins
	  	for( int i = 0; i < level.getRowAmount(); i++){
	  		for( int j = 0; j < level.getColumnAmount(); j++){
	  			g.setColor( Color.BLACK );
	  			String field = level.getField( i, j); 
	  			if( field.equals( "|") && j > 0){
	  				drawVerticalWall( j, i, g);
	  			}else if( field.equals( "L")){
	  				if( j > 0) drawVerticalWall( j, i, g);
	  				if( i < level.getRowAmount()-1) drawHorizontalWall( j, i, g);
	  			}else if( field.equals( "_") && i < level.getRowAmount()-1){
	  				drawHorizontalWall( j, i, g);
	  			}

	  			if( coin != null){
		  			if( coin[i][j]){
		  				g.setColor( Color.YELLOW );
		  				g.fillOval(OFFSET + COINFIELDOFFSET + FIELDSIZE * j,
		  						OFFSET + COINFIELDOFFSET + FIELDSIZE * i,
		  						COINRADIUS * 2, COINRADIUS * 2);
		  				g.setColor(Color.BLACK);
		  				g.drawOval(OFFSET + COINFIELDOFFSET + FIELDSIZE * j,
		  						OFFSET + COINFIELDOFFSET + FIELDSIZE * i,
		  						COINRADIUS * 2, COINRADIUS * 2);
		  			}
	  			}
	  		}
	  	}
	  	
  	}
	  	
  	private void drawHorizontalWall( int x, int y, Graphics g){
			g.fillRect( OFFSET + FIELDSIZE*x,
						OFFSET + FIELDSIZE*y + FIELDSIZE - WALLTHICKNESS/2,
						FIELDSIZE,
						WALLTHICKNESS);
  	}
  	private void drawVerticalWall( int x, int y, Graphics g){
			g.fillRect( OFFSET + FIELDSIZE*x - WALLTHICKNESS/2,
						OFFSET + FIELDSIZE*y,
						WALLTHICKNESS,
						FIELDSIZE);
  	}
  	
	private void drawPlayer( Graphics g, Player p ){
		if( p.GetStatus()==PlayerStatus.DEAD)
			return;
		
		Color color;
		switch(p.GetColor()) {
		case Red: color = Color.RED; break;
		case Blue: color = Color.BLUE; break;
		case Green: color = Color.GREEN; break;
		default: color = Color.BLACK; break;
		}
		g.setColor(color);
		g.fillOval(OFFSET + PLAYERFIELDOFFSET + FIELDSIZE * p.GetPosX(),
				OFFSET + PLAYERFIELDOFFSET + FIELDSIZE * p.GetPosY(),
				PLAYERRADIUS * 2, PLAYERRADIUS * 2);

		g.setColor(Color.BLACK);
		g.drawOval(OFFSET + PLAYERFIELDOFFSET + FIELDSIZE * p.GetPosX(),
				OFFSET + PLAYERFIELDOFFSET + FIELDSIZE * p.GetPosY(),
				PLAYERRADIUS * 2, PLAYERRADIUS * 2);
	}

  	
	public void setLevel(Level l) {
		this.level = l;
		playfieldWidth = FIELDSIZE * (level != null ? level.getColumnAmount() 
										: DEFAULT_FIELD_WIDTH);
		
		playfieldHeight = FIELDSIZE * (level != null ? level.getRowAmount()
										: DEFAULT_FIELD_HEIGHT);
	}
  	
  	
  	public void setPlayer(Player[] p){
  		this.player = p;
  	}
	public void setCoin(Boolean[][] coin) {
		this.coin = coin;
	}

	/*
	 * wird von repaint aufgerufen
	 */
	public void update(Graphics g){	  
		Dimension d = getSize();
		  
	    // check the offscreen image
		if (mImage == null ||
		mImage.getWidth(null) != d.width ||
		mImage.getHeight(null) != d.height){
		mImage = createImage(d.width, d.height);
		}
		 
		Graphics offG = mImage.getGraphics();
		paint(offG); // draw into the offscreen image
		g.drawImage(mImage, 0, 0, null); // display offscreen image
	}

  
	/*
	 * @see javax.swing.JComponent#paint(java.awt.Graphics)
	 */
	public void paint(Graphics g)
	{
		this.draw( g );
	}
	
	public int getPlayfieldWidth() {
		return playfieldWidth;
	}

	public int getPlayfieldHeight() {
		return playfieldHeight;
	}

}
